const Router = require('koa-router')
const { Inventory, InventoryLog, Product, ProductCategory, sequelize } = require('../models')
const auth = require('../middleware/auth')
const { Op } = require('sequelize')

const router = new Router({ prefix: '/api/inventory' })

// 获取库存列表
router.get('/', auth.requirePermission('inventory:read'), async (ctx) => {
  try {
    const {
      page = 1,
      size = 10,
      search = '',
      category_id,
      low_stock = false,
      sort = 'created_at',
      order = 'DESC'
    } = ctx.query

    const offset = (page - 1) * size
    const where = {}

    // 搜索条件
    if (search) {
      where[Op.or] = [
        { '$product.name$': { [Op.like]: `%${search}%` } },
        { '$product.sku$': { [Op.like]: `%${search}%` } }
      ]
    }

    if (category_id) {
      where['$product.category_id$'] = category_id
    }

    // 低库存警告
    if (low_stock === 'true') {
      where[Op.and] = [
        sequelize.where(
          sequelize.col('Inventory.quantity'),
          Op.lte,
          sequelize.col('Inventory.min_stock')
        )
      ]
    }

    const { count, rows } = await Inventory.findAndCountAll({
      where,
      include: [
        {
          model: Product,
          as: 'product',
          include: [
            {
              model: ProductCategory,
              as: 'category',
              attributes: ['id', 'name', 'code']
            }
          ]
        }
      ],
      order: [[sort, order.toUpperCase()]],
      limit: parseInt(size),
      offset
    })

    // 添加库存状态标记
    const inventoryWithStatus = rows.map(inventory => ({
      ...inventory.toJSON(),
      status: inventory.quantity <= inventory.min_stock ? 'low' : 
              inventory.quantity >= inventory.max_stock ? 'high' : 'normal',
      available_quantity: inventory.quantity - inventory.reserved_quantity
    }))

    ctx.body = {
      code: 200,
      message: '获取库存列表成功',
      data: {
        list: inventoryWithStatus,
        total: count,
        page: parseInt(page),
        size: parseInt(size)
      }
    }
  } catch (error) {
    console.error('获取库存列表失败:', error)
    ctx.body = {
      code: 500,
      message: '获取库存列表失败',
      error: error.message
    }
  }
})

// 获取库存详情
router.get('/:id', auth.requirePermission('inventory:read'), async (ctx) => {
  try {
    const { id } = ctx.params

    const inventory = await Inventory.findByPk(id, {
      include: [
        {
          model: Product,
          as: 'product',
          include: [
            {
              model: ProductCategory,
              as: 'category'
            }
          ]
        }
      ]
    })

    if (!inventory) {
      ctx.status = 404
      ctx.body = {
        code: 404,
        message: '库存记录不存在'
      }
      return
    }

    // 获取最近的库存日志
    const recentLogs = await InventoryLog.findAll({
      where: { product_id: inventory.product_id },
      order: [['created_at', 'DESC']],
      limit: 10,
      attributes: ['id', 'type', 'quantity', 'note', 'created_at']
    })

    const result = {
      ...inventory.toJSON(),
      status: inventory.quantity <= inventory.min_stock ? 'low' : 
              inventory.quantity >= inventory.max_stock ? 'high' : 'normal',
      available_quantity: inventory.quantity - inventory.reserved_quantity,
      recent_logs: recentLogs
    }

    ctx.body = {
      code: 200,
      message: '获取库存详情成功',
      data: result
    }
  } catch (error) {
    console.error('获取库存详情失败:', error)
    ctx.body = {
      code: 500,
      message: '获取库存详情失败',
      error: error.message
    }
  }
})

// 更新库存设置
router.put('/:id', auth.requirePermission('inventory:update'), async (ctx) => {
  try {
    const { id } = ctx.params
    const { min_stock, max_stock } = ctx.request.body

    const inventory = await Inventory.findByPk(id)
    if (!inventory) {
      ctx.status = 404
      ctx.body = {
        code: 404,
        message: '库存记录不存在'
      }
      return
    }

    const updateData = {}
    if (min_stock !== undefined) updateData.min_stock = parseInt(min_stock)
    if (max_stock !== undefined) updateData.max_stock = parseInt(max_stock)

    // 验证数据合理性
    if (updateData.min_stock !== undefined && updateData.max_stock !== undefined) {
      if (updateData.min_stock >= updateData.max_stock) {
        ctx.status = 400
        ctx.body = {
          code: 400,
          message: '最小库存不能大于或等于最大库存'
        }
        return
      }
    }

    await inventory.update(updateData)

    ctx.body = {
      code: 200,
      message: '更新库存设置成功',
      data: inventory
    }
  } catch (error) {
    console.error('更新库存设置失败:', error)
    ctx.body = {
      code: 500,
      message: '更新库存设置失败',
      error: error.message
    }
  }
})

// 库存调整（入库/出库）
router.post('/adjust', auth.requirePermission('inventory:update'), async (ctx) => {
  const transaction = await sequelize.transaction()
  
  try {
    const {
      product_id,
      type, // 'in' 或 'out'
      quantity,
      note
    } = ctx.request.body

    // 验证必填字段
    if (!product_id || !type || !quantity || quantity <= 0) {
      ctx.status = 400
      ctx.body = {
        code: 400,
        message: '产品ID、类型和数量为必填项'
      }
      return
    }

    if (!['in', 'out'].includes(type)) {
      ctx.status = 400
      ctx.body = {
        code: 400,
        message: '类型只能是 in 或 out'
      }
      return
    }

    // 验证产品是否存在
    const product = await Product.findByPk(product_id)
    if (!product) {
      ctx.status = 400
      ctx.body = {
        code: 400,
        message: '产品不存在'
      }
      return
    }

    // 获取库存记录
    const inventory = await Inventory.findOne({ where: { product_id } })
    if (!inventory) {
      ctx.status = 400
      ctx.body = {
        code: 400,
        message: '库存记录不存在'
      }
      return
    }

    // 出库时检查库存是否足够
    if (type === 'out' && inventory.quantity < quantity) {
      await transaction.rollback()
      ctx.status = 400
      ctx.body = {
        code: 400,
        message: '库存不足'
      }
      return
    }

    // 更新库存数量
    const quantityChange = type === 'in' ? quantity : -quantity
    await inventory.increment({ quantity: quantityChange }, { transaction })

    // 记录库存日志
    await InventoryLog.create({
      product_id,
      type,
      quantity,
      before_quantity: inventory.quantity,
      after_quantity: inventory.quantity + quantityChange,
      note,
      created_by: ctx.state.user.id
    }, { transaction })

    await transaction.commit()

    // 获取更新后的库存信息
    const updatedInventory = await Inventory.findByPk(inventory.id, {
      include: [
        {
          model: Product,
          as: 'product'
        }
      ]
    })

    ctx.body = {
      code: 200,
      message: '库存调整成功',
      data: updatedInventory
    }
  } catch (error) {
    await transaction.rollback()
    console.error('库存调整失败:', error)
    ctx.body = {
      code: 500,
      message: '库存调整失败',
      error: error.message
    }
  }
})

// 获取库存日志
router.get('/logs', auth.requirePermission('inventory:read'), async (ctx) => {
  try {
    const {
      page = 1,
      size = 10,
      product_id,
      type,
      date_from,
      date_to,
      sort = 'created_at',
      order = 'DESC'
    } = ctx.query

    const offset = (page - 1) * size
    const where = {}

    if (product_id) {
      where.product_id = product_id
    }

    if (type) {
      where.type = type
    }

    // 日期范围查询
    if (date_from && date_to) {
      where.created_at = {
        [Op.between]: [new Date(date_from), new Date(date_to)]
      }
    } else if (date_from) {
      where.created_at = {
        [Op.gte]: new Date(date_from)
      }
    } else if (date_to) {
      where.created_at = {
        [Op.lte]: new Date(date_to)
      }
    }

    const { count, rows } = await InventoryLog.findAndCountAll({
      where,
      include: [
        {
          model: Product,
          as: 'product',
          attributes: ['id', 'name', 'sku']
        }
      ],
      order: [[sort, order.toUpperCase()]],
      limit: parseInt(size),
      offset
    })

    ctx.body = {
      code: 200,
      message: '获取库存日志成功',
      data: {
        list: rows,
        total: count,
        page: parseInt(page),
        size: parseInt(size)
      }
    }
  } catch (error) {
    console.error('获取库存日志失败:', error)
    ctx.body = {
      code: 500,
      message: '获取库存日志失败',
      error: error.message
    }
  }
})

// 获取库存统计信息
router.get('/stats/summary', auth.requirePermission('inventory:read'), async (ctx) => {
  try {
    const inventories = await Inventory.findAll({
      include: [
        {
          model: Product,
          as: 'product',
          attributes: ['id', 'name', 'price']
        }
      ]
    })

    const stats = {
      total_products: inventories.length,
      total_quantity: inventories.reduce((sum, inv) => sum + inv.quantity, 0),
      total_value: inventories.reduce((sum, inv) => {
        const price = inv.product ? parseFloat(inv.product.price || 0) : 0
        return sum + (inv.quantity * price)
      }, 0),
      low_stock_count: inventories.filter(inv => inv.quantity <= inv.min_stock).length,
      out_of_stock_count: inventories.filter(inv => inv.quantity === 0).length,
      reserved_quantity: inventories.reduce((sum, inv) => sum + inv.reserved_quantity, 0)
    }

    ctx.body = {
      code: 200,
      message: '获取库存统计信息成功',
      data: stats
    }
  } catch (error) {
    console.error('获取库存统计信息失败:', error)
    ctx.body = {
      code: 500,
      message: '获取库存统计信息失败',
      error: error.message
    }
  }
})

// 获取低库存警告
router.get('/alerts/low-stock', auth.requirePermission('inventory:read'), async (ctx) => {
  try {
    const lowStockItems = await Inventory.findAll({
      where: {
        [Op.and]: [
          sequelize.where(
            sequelize.col('Inventory.quantity'),
            Op.lte,
            sequelize.col('Inventory.min_stock')
          )
        ]
      },
      include: [
        {
          model: Product,
          as: 'product',
          include: [
            {
              model: ProductCategory,
              as: 'category',
              attributes: ['id', 'name']
            }
          ]
        }
      ],
      order: [['quantity', 'ASC']]
    })

    const alerts = lowStockItems.map(item => ({
      ...item.toJSON(),
      alert_level: item.quantity === 0 ? 'critical' : 'warning',
      shortage: Math.max(0, item.min_stock - item.quantity)
    }))

    ctx.body = {
      code: 200,
      message: '获取低库存警告成功',
      data: alerts
    }
  } catch (error) {
    console.error('获取低库存警告失败:', error)
    ctx.body = {
      code: 500,
      message: '获取低库存警告失败',
      error: error.message
    }
  }
})

module.exports = router